package com.zhentao.confeifr;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.zhentao.dao.PermissionMapper;
import com.zhentao.pojo.Permission;
import com.zhentao.pojo.User;
import com.zhentao.tokenfile.TokenFile;
import com.zhentao.util.JwtService;
import com.zhentao.util.Result;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.function.Supplier;

@Configuration
@EnableWebSecurity
public class Tokenwes {
    @Autowired
    PermissionMapper permissionMapper;
    @Autowired
    TokenFile tokenFile;

//    @Bean
//    public SecurityFilterChain getSecurityFilterChain(HttpSecurity http) throws Exception {
//        http.authorizeHttpRequests(conf->conf.requestMatchers("/user/login","/user/logout","/error")
//                .permitAll()
//                .anyRequest()
//                .access(this::check)
//        );
//        http.formLogin(conf->conf.loginProcessingUrl("/user/login")
//                .successHandler(this::aa)
//                .failureHandler(this::bb)
//        );
//        http.exceptionHandling(conf->conf.authenticationEntryPoint(this::onlogin).accessDeniedHandler(this::guanli));
//        http.sessionManagement(conf->conf.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
//        http.logout(conf->conf.logoutUrl("/user/logout").logoutSuccessHandler(this::outlogin));
//        http.addFilterBefore(tokenFile, UsernamePasswordAuthenticationFilter.class);
//        return http.build();
//    }
//@Bean
//public BCryptPasswordEncoder getBCryptPasswordEncoder(){
//        return new BCryptPasswordEncoder();
//}
//    private void outlogin(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
//        Result ok = Result.ERROR("登出成功");
//        response.setContentType("application/json;charset=utf-8");
//        PrintWriter writer = response.getWriter();
//        String string = JSON.toJSONString(ok);
//        writer.write(string);
//    }
//
//    private void onlogin(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException {
//        Result ok = Result.ERROR("未登录");
//        response.setContentType("application/json;charset=utf-8");
//        PrintWriter writer = response.getWriter();
//        String string = JSON.toJSONString(ok);
//        writer.write(string);
//    }
//
//    private void guanli(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException {
//        Result ok = Result.ERROR("权限不足");
//        response.setContentType("application/json;charset=utf-8");
//        PrintWriter writer = response.getWriter();
//        String string = JSON.toJSONString(ok);
//        writer.write(string);
//    }
//
//    private void aa(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
//        User user = (User) authentication.getPrincipal();
//        HashMap<String, Object> objectObjectHashMap = new HashMap<>();
//        objectObjectHashMap.put("username",user.getUsername());
//        objectObjectHashMap.put("uid",user.getUid());
//        objectObjectHashMap.put("perms",user.getPerms());
//        objectObjectHashMap.put("rName",user.getRName());
//        String token = JwtService.createToken(objectObjectHashMap);
//        Result ok = Result.OK(token);
//        response.setContentType("application/json;charset=utf-8");
//        PrintWriter writer = response.getWriter();
//        String string = JSON.toJSONString(ok);
//        writer.write(string);
//    }
//
//    private void bb(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException {
//        Result ok = Result.ERROR("登陆失败");
//        response.setContentType("application/json;charset=utf-8");
//        PrintWriter writer = response.getWriter();
//        String string = JSON.toJSONString(ok);
//        writer.write(string);
//    }
//
//    private AuthorizationDecision check(Supplier<Authentication> authenticationSupplier, RequestAuthorizationContext context) {
//                Object u = authenticationSupplier.get().getPrincipal();
//        if(u instanceof String){
//            return new AuthorizationDecision(false);
//        }
//        HttpServletRequest request = context.getRequest();
//        String requestURI = request.getRequestURI();
//        QueryWrapper<Permission> objectQueryWrapper = new QueryWrapper<>();
//        objectQueryWrapper.eq("path",requestURI);
//        Permission permission = permissionMapper.selectOne(objectQueryWrapper);
//        if(permission!=null){
//            String pname = permission.getPname();
//            User user = (User) u;
//            List<String> perms = user.getPerms();
//            if(perms.contains(pname)){
//                return new AuthorizationDecision(true);
//            }
//        }
//        return new AuthorizationDecision(false);
//    }


    @Bean
    public SecurityFilterChain getSecurityFilterChain(HttpSecurity http) throws Exception {
        http.csrf(conf->conf.disable());
        http.authorizeHttpRequests(conf->conf.requestMatchers("/user/login","/user/logout","/error")
                .permitAll()
                .anyRequest()
                .access(this::check)
        );
        http.formLogin(conf->conf.loginProcessingUrl("/user/login")
                .successHandler(this::aa)
                .failureHandler(this::bb)
        );
        http.exceptionHandling(conf->conf.authenticationEntryPoint(this::outlogin).accessDeniedHandler(this::guanli));
        http.sessionManagement(conf->conf.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
        http.logout(conf->conf.logoutUrl("/user/logout").logoutSuccessHandler(this::nologin));
        http.addFilterBefore(tokenFile, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }
@Bean
public BCryptPasswordEncoder getBCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
}
    private void nologin(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        Result ok = Result.ERROR("登出成功");
        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer = response.getWriter();
        String string = JSON.toJSONString(ok);
        writer.write(string);
    }

    private void outlogin(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException {
        Result ok = Result.ERROR("请先登录");
        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer = response.getWriter();
        String string = JSON.toJSONString(ok);
        writer.write(string);
    }

    private void guanli(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException {
        Result ok = Result.OK("权限不足，请联系管理员");
        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer = response.getWriter();
        String string = JSON.toJSONString(ok);
        writer.write(string);
    }

    private void bb(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException {
        Result ok = Result.ERROR("登陆失败请检查账号或密码");
        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer = response.getWriter();
        String string = JSON.toJSONString(ok);
        writer.write(string);
    }

    private void aa(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        User user = (User) authentication.getPrincipal();
        HashMap<String, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("username",user.getUsername());
        objectObjectHashMap.put("uid",user.getUid());
        objectObjectHashMap.put("perms",user.getPerms());
        objectObjectHashMap.put("rName",user.getRName());
        String token = JwtService.createToken(objectObjectHashMap);
        Result ok = Result.OK(token);
        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer = response.getWriter();
        String string = JSON.toJSONString(ok);
        writer.write(string);
    }
    private AuthorizationDecision check(Supplier<Authentication> authenticationSupplier, RequestAuthorizationContext context) {
        Object u = authenticationSupplier.get().getPrincipal();
        if(u instanceof String){
            return new AuthorizationDecision(false);
        }
        HttpServletRequest request = context.getRequest();
        String requestURI = request.getRequestURI();
        QueryWrapper<Permission> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("path",requestURI);
        Permission permission = permissionMapper.selectOne(objectQueryWrapper);
        if(permission!=null){
            String pname = permission.getPname();
            User user = (User) u;
            List<String> perms = user.getPerms();
            if(perms.contains(pname)){
                return new AuthorizationDecision(true);
            }
        }
        return new AuthorizationDecision(false);
    }


//@Bean
//    public SecurityFilterChain getSecurityFilterChain(HttpSecurity http) throws Exception {
//        http.csrf(conf->conf.disable());
//        http.authorizeHttpRequests(conf->conf.requestMatchers("/user/login","/user/logout","/error")
//                .permitAll()
//                .anyRequest()
//                .access(this::check)
//        );
//        http.formLogin(conf->conf.loginProcessingUrl("/user/login")
//                .successHandler(this::aa)
//                .failureHandler(this::bb)
//        );
//        http.exceptionHandling(conf->conf.authenticationEntryPoint(this::onlogin).accessDeniedHandler(this::guanli));
//        http.sessionManagement(conf->conf.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
//        http.logout(conf->conf.logoutUrl("/user/logout").logoutSuccessHandler(this::outlogin));
//        http.addFilterBefore(tokenFile, UsernamePasswordAuthenticationFilter.class);
//        return http.build();
//    }
//
//    private void outlogin(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
//        Result ok = Result.ERROR("等处成功");
//        response.setContentType("application/json;charset=utf-8");
//        PrintWriter writer = response.getWriter();
//        String string = JSON.toJSONString(ok);
//        writer.write(string);
//    }
//
//    private void onlogin(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException {
//        Result ok = Result.ERROR("您还没登陆，请您登录");
//        response.setContentType("application/json;charset=utf-8");
//        PrintWriter writer = response.getWriter();
//        String string = JSON.toJSONString(ok);
//        writer.write(string);
//    }
//
//    private void guanli(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException {
//        Result ok = Result.ERROR("您当前没有权限，请联系管理员");
//        response.setContentType("application/json;charset=utf-8");
//        PrintWriter writer = response.getWriter();
//        String string = JSON.toJSONString(ok);
//        writer.write(string);
//    }
//
//    @Bean
//public BCryptPasswordEncoder getBCryptPasswordEncoder(){
//        return new BCryptPasswordEncoder();
//}
//    private void bb(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException {
//        Result ok = Result.ERROR("登陆失,请检查你的账号或密码是否正确");
//        response.setContentType("application/json;charset=utf-8");
//        PrintWriter writer = response.getWriter();
//        String string = JSON.toJSONString(ok);
//        writer.write(string);
//    }
//
//    private void aa(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
//        User user = (User) authentication.getPrincipal();
//        HashMap<String, Object> objectObjectHashMap = new HashMap<>();
//        objectObjectHashMap.put("username",user.getUsername());
//        objectObjectHashMap.put("uid",user.getUid());
//        objectObjectHashMap.put("perms",user.getPerms());
//        objectObjectHashMap.put("rName",user.getRName());
//        String token = JwtService.createToken(objectObjectHashMap);
//        Result ok = Result.OK(token);
//        response.setContentType("application/json;charset=utf-8");
//        PrintWriter writer = response.getWriter();
//        String string = JSON.toJSONString(ok);
//        writer.write(string);
//
//
//    }
//
//    private AuthorizationDecision check(Supplier<Authentication> authenticationSupplier, RequestAuthorizationContext context) {
//        Object u = authenticationSupplier.get().getPrincipal();
//        if(u instanceof String){
//            return new AuthorizationDecision(false);
//        }
//        HttpServletRequest request = context.getRequest();
//        String requestURI = request.getRequestURI();
//        QueryWrapper<Permission> objectQueryWrapper = new QueryWrapper<>();
//        objectQueryWrapper.eq("path",requestURI);
//        Permission permission = permissionMapper.selectOne(objectQueryWrapper);
//        if(permission!=null){
//            String pname = permission.getPname();
//            User user = (User) u;
//            List<String> perms = user.getPerms();
//            if(perms.contains(pname)){
//                return new AuthorizationDecision(true);
//            }
//        }
//        return new AuthorizationDecision(false);
//    }

}
